<template>
  <a-drawer
    width="100%"
    placement="right"
    :visible="drawer.visible"
    :bodyStyle="drawer.bodyStyle"
    @close="cancel"
  >
    <a-steps :current="steps.current" @change="onStepChange" size="small">
      <a-step
        v-for="item in steps.tab"
        :key="item.title"
        :title="item.title"
        :description="item.description"
      />
    </a-steps>
    <div class="steps-content">
      <div v-show="steps.current == 0">
        <a-spin :spinning="spinning">
          <k-form-design
            ref="kfd"
            toolbarsTop
            :destroyOnClose="true"
            :showToolbarsText="true"
            :showHead="false"
            :toolbars="design.toolbars"
            :style="{ height: height.edit + 'px' }"
            @save="editFormSave"
          >
            <!-- 左侧操作区域插槽 start -->
            <template slot="left-action">
              <a-tooltip title="发布表单" @click="editFormPublic">
                <a>
                  <a-icon type="build" />
                  <span>发布</span>
                </a>
              </a-tooltip>
            </template>
            <!-- 左侧操作区域插槽 end -->
            <!-- 右侧操作区域插槽 start -->
            <template slot="right-action">
              <a-tooltip :title="title">{{ title }}</a-tooltip>
            </template>
            <!-- 右侧操作区域插槽 end -->
          </k-form-design>
        </a-spin>
      </div>

      <div v-show="steps.current == 1">
        <a-card title="列表字段" size="small">
          <div slot="extra">
            <a-space>
              <a-checkbox :checked="list.isPaging" @change="isPagingChange"
                >分页</a-checkbox
              >
              <a-checkbox :checked="list.isMultiple" @change="isMultipleChange"
                >多选</a-checkbox
              >
              <a-input
                v-model="list.height"
                type="number"
                style="width: 180px"
                default-value="800"
                placeholder="请选择高度"
              >
                <div slot="addonAfter">px</div>
                <div slot="addonBefore">高度</div>
              </a-input>

              <a-input
                disabled
                placeholder="点击选择设置查询条件"
                v-model="list.search.title"
              >
                <div
                  @click="searchClick"
                  slot="addonAfter"
                  style="cursor: pointer"
                >
                  <a-icon type="search" />查询设置
                </div>
              </a-input>
              <a-button @click="tableSave" type="primary">保存</a-button>
              <a-button @click="tablePublic" type="primary">发布</a-button>
            </a-space>
          </div>

          <vxe-table
            ref="table"
            row-key
            :loading="loading"
            :height="height.list"
            :data="list.controls"
          >
            <vxe-table-column title="排序" width="50" align="center">
              <template>
                <span class="drag-btn">
                  <a-icon type="drag" />
                </span>
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="isShow"
              title="显示"
              align="center"
              width="50"
            >
              <template v-slot="{ row }">
                <a-checkbox
                  :checked="row.isShow"
                  @change="isShowChange(row, $event)"
                />
              </template>
            </vxe-table-column>

            <vxe-table-column
              field="isSearch"
              title="查询"
              align="center"
              width="50"
            >
              <template v-slot="{ row }">
                <a-checkbox
                  :checked="row.isSearch"
                  @change="isSearchChange(row, $event)"
                />
              </template>
            </vxe-table-column>
            <vxe-table-column field="name" title="字段名" width="120">
              <template v-slot="{ row }">{{ row.name }}</template>
            </vxe-table-column>
            <vxe-table-column
              field="description"
              title="标题"
              align="center"
              width="120"
            >
              <template v-slot="{ row }">
                <a-input placeholder="请输入标题" v-model="row.description" />
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="align"
              title="对齐"
              align="center"
              width="80"
            >
              <template v-slot="{ row }">
                <a-select v-model="row.align" placeholder="请选择对齐方式">
                  <a-select-option value="left">左</a-select-option>
                  <a-select-option value="center">中</a-select-option>
                  <a-select-option value="right">右</a-select-option>
                </a-select>
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="width"
              title="宽度(px)"
              align="center"
              width="110"
            >
              <template v-slot="{ row }">
                <a-input-number
                  style="width: 80px"
                  placeholder="请输入宽度(px)"
                  v-model="row.width"
                />
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="templet"
              title="格式化"
              align="center"
              width="120"
            >
              <template v-slot="{ row }">
                <a-select
                  placeholder="请选择格式化"
                  v-model="row.templet"
                  style="width: 100px"
                >
                  <a-select-option value="HHMMSS">HH:mm:ss</a-select-option>
                  <a-select-option value="YYYYMMDD">yyyy-MM-dd</a-select-option>
                  <a-select-option value="YYYYMMDDHHMMSS"
                    >yyyy-MM-dd HH:mm:ss</a-select-option
                  >
                  <a-select-option value="Icon">图标</a-select-option>
                  <a-select-option value="Sex">性别</a-select-option>
                  <a-select-option value="Freeze">禁用</a-select-option>
                  <a-select-option value="YesOrNo">是否</a-select-option>
                  <a-select-option value="Delete">删除</a-select-option>
                  <a-select-option value="WorkFlowStatus"
                    >流程状态</a-select-option
                  >
                  <a-select-option value="Image">图片</a-select-option>
                </a-select>
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="fixed"
              title="固定"
              align="center"
              width="80"
            >
              <template v-slot="{ row }">
                <a-select
                  placeholder="请选择固定"
                  v-model="row.fixed"
                  style="width: 60px"
                >
                  <a-select-option value="left">左</a-select-option>
                  <a-select-option value="right">右</a-select-option>
                </a-select>
              </template>
            </vxe-table-column>
            <vxe-table-column title="排序" align="center" width="210">
              <template v-slot="{ row }">
                <a-checkbox
                  :checked="row.isSort"
                  @change="isSortChange(row, $event)"
                  >排序</a-checkbox
                >
                <a-checkbox
                  :checked="row.isSortDefalut"
                  @change="isSortDefalutChange(row, $event)"
                  >默认</a-checkbox
                >
                <a-checkbox
                  :checked="row.isSortAsc"
                  @change="isSortAscChange(row, $event)"
                  >Asc</a-checkbox
                >
              </template>
            </vxe-table-column>
            <vxe-table-column
              field="isTotal"
              title="合计"
              align="center"
              width="50"
            >
              <template v-slot="{ row }">
                <a-checkbox
                  :checked="row.isTotal"
                  @change="isTotalChange(row, $event)"
                ></a-checkbox>
              </template>
            </vxe-table-column>
            <vxe-table-column title="子表" align="center" min-width="300px">
              <template v-slot="{ row }">
                <a-input-group compact>
                  <a-select
                    placeholder="请选择子表"
                    v-model="row.subtable.id"
                    mode="multiple"
                    style="width: 80%"
                  >
                    <a-select-option
                      v-for="(item, i) in row.subtable.all"
                      :key="i"
                      :value="item.configId"
                      >{{ item.name }}</a-select-option
                    >
                  </a-select>
                  <a-button @click="subtableClick(row)">
                    <a-icon type="search"></a-icon>
                  </a-button>
                </a-input-group>
              </template>
            </vxe-table-column>
            <vxe-table-column title="弹出" align="center" width="160">
              <template v-slot="{ row }">
                <a-input-group compact>
                  <a-select
                    placeholder="请选择弹出"
                    v-model="row.dialog.id"
                    style="width: 90px"
                  >
                    <a-select-option
                      v-for="(item, i) in row.subtable.all"
                      :key="i"
                      :value="item.configId"
                      >{{ item.name }}</a-select-option
                    >
                  </a-select>
                  <a-button @click="dialogClick(row)">
                    <a-icon type="setting"></a-icon>
                  </a-button>
                </a-input-group>
              </template>
            </vxe-table-column>
            <vxe-table-column title="多表头名称" align="center" width="120">
              <template v-slot="{ row }">
                <a-input placeholder="请输入标题" v-model="row.header.title" />
              </template>
            </vxe-table-column>
            <vxe-table-column title="多表头字段" align="center" width="150">
              <template v-slot="{ row }">
                <a-select
                  placeholder="请选择多表头字段"
                  v-model="row.header.field"
                  mode="multiple"
                  style="width: 130px"
                >
                  <a-select-option
                    v-for="(item, i) in row.controls"
                    :key="i"
                    :value="item.model"
                    >{{ item.label }}</a-select-option
                  >
                </a-select>
              </template>
            </vxe-table-column>
            <vxe-table-column title="样式" align="center" width="80">
              <template v-slot="{ row }">
                <a-button @click="styleClick(row)" type="primary"
                  >设置</a-button
                >
              </template>
            </vxe-table-column>
          </vxe-table>
        </a-card>
        <br />
      </div>
    </div>
    <div class="steps-action">
      <a-space>
        <a-button :disabled="steps.current != 1" @click="prev">上一步</a-button>
        <a-button :disabled="steps.current != 0" @click="next">下一步</a-button>
        <a-button type="danger" @click="cancel"
          ><a-icon type="close" />取消</a-button
        >
      </a-space>
    </div>

    <list-subtable
      :visible.sync="drawer.subtable.visible"
      ref="listSubtable"
      @ok="subtableOk"
    />
    <list-dialog
      :visible.sync="drawer.dialog.visible"
      ref="listDialog"
      @ok="dialogOk"
    />

    <list-style
      :visible.sync="drawer.style.visible"
      ref="listStyle"
      @ok="styleOk"
    />

    <search-index
      ref="search"
      :visible.sync="drawer.search.visible"
      @ok="searchOk"
    />
  </a-drawer>
</template>

<script>
import searchIndex from "@/pages/system/agile/common/search/index";
import listSubtable from "@/pages/system/agile/common/list/subtable";
import listDialog from "@/pages/system/agile/common/list/dialog";
import listStyle from "@/pages/system/agile/common/list/style";
import Sortable from "sortablejs";
import {
  findById,
  editSave,
  editPublic,
  listSave,
  listPublic,
  tableField,
} from "@/services/system/agile/desinger/data/desinger";

import { query } from "@/services/system/agile/desinger/data/list";
export default {
  name: "businessdatadesinger",
  components: {
    searchIndex,
    listSubtable,
    listDialog,
    listStyle,
  },
  data() {
    return {
      col: {
        label: { span: 4 },
        wrapper: { span: 18 },
      },

      steps: {
        current: 0,
        tab: [
          {
            title: "表单设计器",
            description: "",
          },
          {
            title: "列表设计器",
            description: "",
          },
        ],
      },

      design: {
        toolbars: [
          "save",
          "preview",
          "importJson",
          "exportJson",
          "exportCode",
          "reset",
        ],
      },

      height: {
        edit: window.innerHeight - 116,
        list: window.innerHeight - 210,
      },

      form: {
        configId: "",
      },

      drawer: {
        visible: this.visible,
        bodyStyle: {
          padding: "10px",
          "padding-bottom": "4px",
        },
        subtable: {
          visible: false,
          zIndex: 9999,
        },

        dialog: {
          visible: false,
          zIndex: 1040,
        },

        style: {
          visible: false,
        },

        search: {
          visible: false,
        },
      },

      loading: false,
      spinning: false,

      controls: [],
      edit: {
        controls: [], //所有控件信息
      },

      list: {
        height: 800,
        controls: [], //表格记录控件
        isPaging: true, //是否分页
        isMultiple: true, //是否多选
        search: {
          title: null, //查询标题
          config: {
            num: 3,
            fields: [],
          }, //配置
        },
      },

      subtableItem: {},
      dialogItem: {},
      styleItem: {},
      allAgileConfig: [], //所有已配置敏捷开发表单,用作子表选择
    };
  },

  watch: {
    visible(val) {
      this.drawer.visible = val;
    },
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },

    title: {
      type: String,
    },
  },

  methods: {
    /**
     * 拖拽
     */
    rowDrop() {
      let that = this;
      const xTable = this.$refs.table;
      Sortable.create(
        xTable.$el.querySelector(".body--wrapper>.vxe-table--body tbody"),
        {
          handle: ".drag-btn",
          onEnd: ({ newIndex, oldIndex }) => {
            const currRow = that.controlsList.splice(oldIndex, 1)[0];
            that.controlsList.splice(newIndex, 0, currRow);
          },
        }
      );
    },

    /**
     * 上一步
     */
    next() {
      this.steps.current++;
      this.stepChange();
    },

    /**
     * 下一步
     */
    prev() {
      this.steps.current--;
      this.stepChange();
    },

    /**
     * 改变
     */
    onStepChange(current) {
      this.steps.current = current;
      this.stepChange();
    },

    /**
     * 取消
     */
    cancel() {
      this.$emit("update:visible", false);
    },

    /**
     * 保存表单设计
     */
    editFormSave(values) {
      let that = this;
      this.controls = JSON.parse(values);
      let param = {
        configId: this.form.configId,
        edit: values,
      };
      that.$loading.show({ text: "保存中,请稍等..." });
      editSave(param).then(function (result) {
        that.$loading.hide();
        if (result.code === that.eipResultCode.success) {
          that.$message.success(result.msg);
        } else {
          that.$message.error(result.msg);
        }
      });
    },

    /**
     * 获取控件字段类型
     */
    editFormFieldType(control) {
      switch (control.type) {
        case "input": //输入框
        case "textarea": //文本框
          var maxLength = control.options.maxLength
            ? control.options.maxLength
            : 1024;
          return `nvarchar(${maxLength})`;
        case "number": //数字输入框
          //判断是否具有小数点
          if (control.precision) {
            return `numeric(18, ${control.precision})`;
          } else {
            return `int`;
          }
        case "checkbox":
        case "radio":
        case "select":
        case "editor":
          return `nvarchar(512)`;
        case "date":
          return `datetime`;
        case "time":
          return `nvarchar(8)`;
        case "rate":
          return `numeric(18, 1)`;
        case "slider":
          return `numeric(18, 2)`;
        case "switch":
          return `bit`;
      }
    },

    /**
     * 发布表单设计
     */
    editFormPublic() {
      let that = this;
      const modal = this.$confirm({
        okText: "确认",
        cancelText: "取消",
        title: "表单发布提示",
        content: "若已发布会覆盖原来表结构，且不可恢复？",
        onOk() {
          modal.destroy();
          let controls = that.$refs.kfd.getValue();
          let param = {
            configId: that.form.configId,
            edit: JSON.stringify(controls),
            editPublic: JSON.stringify(controls),
          };
          //创建修改字段
          let columns = [];
          //解析字段
          controls.list.forEach((control) => {
            let column = {
              name: control.model, //字段名
              type: that.editFormFieldType(control), //字段类型
              description: control.label, //描述
              null: control.rules.filter((f) => f.required).length == 0, //是否可为空
              controlType: control.type, //组件类型
            };
            switch (column.controlType) {
              case "batch": //子表
                column.subtable = {
                  table: control.subtabletable, //子表名称
                  description: control.subtabletabledescription, //子表描述
                  config: control.config, //子表配置
                };
                break;
              case "checkbox": //复选框
                column.issingle = false; //是否为单选,若为多选则新建关系表
                break;
              case "organization": //组织架构
              case "dictionary": //字典
              case "user": //用户
              case "select": //选择框
                break;
              default:
                break;
            }
            columns.push(column);
          });
          if (columns.length == 0) {
            that.$message.error("请添加控件");
            return false;
          }
          let publicParam = {
            configId: that.form.configId,
            columns: JSON.stringify(columns),
          };
          that.$loading.show({ text: "发布中,请稍等..." });
          that.spinning = true;
          tableField(publicParam).then(function (result) {
            that.$loading.hide();
            if (result.code === that.eipResultCode.success) {
              editPublic(param).then(function (result) {
                that.spinning = false;
                if (result.code === that.eipResultCode.success) {
                  that.$message.success(result.msg);
                } else {
                  that.$message.error(result.msg);
                }
              });
            } else {
              that.$message.error(result.msg);
            }
          });
        },
        onCancel() {},
      });
    },

    /**
     * 根据Id查找
     */
    find(configId) {
      let that = this;
      that.spinning = true;
      that.steps.current = 0;
      that.list.controls = [];
      findById(configId).then(function (result) {
        let form = result.data;
        that.form.configId = configId;
        if (form.edit) {
          that.$refs.kfd.handleSetData(JSON.parse(form.edit));
        } else {
          let def = {
            list: [],
            config: {
              layout: "horizontal",
              labelCol: {
                xs: 4,
                sm: 4,
                md: 4,
                lg: 4,
                xl: 4,
                xxl: 4,
              },
              wrapperCol: {
                xs: 18,
                sm: 18,
                md: 18,
                lg: 18,
                xl: 18,
                xxl: 18,
              },
              event: {
                before: "",
                after: "",
              },
              api: {
                before: "",
                after: "",
              },
              button: {
                submit: {
                  name: "保存",
                  success: 0,
                },
              },
              hideRequiredMark: false,
            },
          };
          that.$refs.kfd.handleSetData(def);
        }
        if (form.list) {
          that.list = JSON.parse(form.list);
        } else {
          that.list = {
            height: 800,
            controls: [], //表格记录控件
            isPaging: true, //是否分页
            isMultiple: true, //是否多选
            search: {
              title: null, //查询标题
              config: {
                num: 3,
                fields: [],
              }, //配置
            },
          };
        }

        that.spinning = false;
        that.rowDrop();
      });
    },

    /**
     * 步骤改变
     */
    stepChange() {
      switch (this.steps.current) {
        case 0: //表单设计器
          break;
        case 1: //列表生成器
          this.design.isPublic = false;
          //保存设计内容
          this.stepChangeOk();
          break;
      }
    },

    /**
     * 改变保存
     */
    stepChangeOk() {
      let that = this;
      this.controls = this.$refs.kfd.getValue();
      let param = {
        configId: this.form.configId,
        edit: JSON.stringify(this.controls),
      };
      editSave(param).then(function (result) {
        if (result.code === that.eipResultCode.success) {
          that.editAllControls();
          that.tableSetData();
        } else {
          that.$message.error(result.msg);
        }
      });
    },

    /**
     * 获取表单设计器组件
     */
    editAllControls() {
      let that = this;
      that.edit.controls = [];
      //解析字段
      this.controls.list.forEach((control) => {
        if (
          control.type == "files" ||
          control.type == "files" ||
          control.type == "subtable" ||
          control.type == "script"
        )
          return;

        let column = {
          name: control.model, //字段名
          description: control.label, //描述
          type: that.editFormFieldType(control), //字段类型
          controlType: control.type, //组件类型
        };

        that.edit.controls.push(column);
      });
    },

    /**
     * 子表规则点击
     */
    subtableClick(item) {
      this.drawer.subtable.visible = true;
      this.subtableItem = item;
      this.$refs.listSubtable.init(this.subtableItem.subtable.config);
    },

    /**
     * 子表规则保存
     */
    subtableOk(config) {
      this.subtableItem.subtable.config = config;
      this.subtableCancel();
    },

    /**
     * 弹出框点击
     */
    dialogClick(item) {
      this.drawer.dialog.visible = true;
      this.dialogItem = item;
      this.$refs.listDialog.init(this.dialogItem.dialog.config);
    },

    /**
     * 弹出框规则保存
     */
    dialogOk(config) {
      this.dialogItem.style = config;
      this.dialogCancel();
    },

    /**
     * 弹出框点击
     */
    styleClick(item) {
      this.drawer.style.visible = true;
      this.styleItem = item;
      this.$refs.listStyle.init(this.styleItem.style);
    },
    /**
     * 弹出框规则取消
     */
    styleCancel() {
      this.drawer.style.visible = false;
    },
    /**
     * 弹出框规则保存
     */
    styleOk(config) {
      this.styleItem.style = config;
      this.styleCancel();
    },

    /**
     * 赋予表格数据
     */
    tableSetData() {
      let that = this;
      that.loading = true;
      let param = {
        limit: 9999,
        sidx: "OrderNo",
        type: 1,
      };
      query(param).then(function (result) {
        let columns = [];
        that.list.controls.forEach((item) => {
          let have = that.edit.controls.filter(
            (f) => f.name == item.name
          ).length;
          if (have > 0) {
            columns.push(item);
          }
        });

        that.edit.controls.forEach((item) => {
          let column = {};
          //是否在已配置里面
          let have = that.list.controls.filter(
            (f) => f.name == item.name
          ).length;

          if (have == 0) {
            column.isShow = true;
            column.isSearch = true;
            column.isSort = true;
            column.isSortDefalut = null;
            column.isSortAsc = null;
            column.isTotal = null;
            column.name = item.name;
            column.description = item.description;
            column.type = item.type;
            column.typedata = item.typedata;
            column.width = 100;
            column.align = "left";
            column.fixed = null;
            column.templet = [];

            column.subtable = {
              all: result.data,
              config: {
                condition: null,
              },
              id: [],
            };

            column.dialog = {
              config: {
                condition: null,
                height: 200,
                heightUnit: ["px"],
                width: 300,
                widthUnit: ["px"],
              },
              id: [],
            };

            column.header = {
              title: null,
              field: [],
            };

            column.style = [];
            column.controls =
              that.list.controls.length == 0
                ? that.controls.list
                : that.list.controls;
            columns.push(column);
          }
        });
        that.list.controls = columns;
        that.loading = false;
      });
    },

    /**
     * 表格配置保存
     */
    tableSave() {
      let that = this;
      let form = {
        configId: this.form.configId,
        list: JSON.stringify(this.list),
      };
      that.$loading.show({ text: "保存中,请稍等..." });
      listSave(form).then(function (result) {
        that.$loading.hide();
        if (result.code === that.eipResultCode.success) {
          that.$message.success(result.msg);
        } else {
          that.$message.error(result.msg);
        }
      });
    },

    /**
     * 表格配置发布
     */
    tablePublic() {
      let that = this;
      const modal = this.$confirm({
        okText: "确认",
        cancelText: "取消",
        title: "表单发布提示",
        content: "若已发布会覆盖原来结构，且不可恢复？",
        onOk() {
          modal.destroy();
          let form = {
            configId: that.form.configId,
            list: JSON.stringify(that.list),
            listPublic: JSON.stringify(that.list),
          };
          that.$loading.show({ text: "发布中,请稍等..." });
          listPublic(form).then(function (result) {
            that.$loading.hide();
            if (result.code === that.eipResultCode.success) {
              that.$message.success(result.msg);
            } else {
              that.$message.error(result.msg);
            }
          });
        },
        onCancel() {},
      });
    },

    /**
     * 查询配置点击
     */
    searchClick() {
      this.drawer.search.visible = true;
      this.$refs.search.init(this.list.search.config);
    },

    /**
     * 查询配置关闭
     */
    searchCancel() {
      this.drawer.search.visible = false;
    },

    /**
     * 查询配置保存
     */
    searchOk(config) {
      this.list.search.config = config;
      let titles = [];
      config.fields.forEach((item) => {
        titles.push(item.title);
      });
      this.list.search.title = titles.join(",");
      this.searchCancel();
    },

    /**
     *显示改变
     */
    isShowChange(item, e) {
      item.isShow = e.target.checked;
    },

    /**
     *查询改变
     */
    isSearchChange(item, e) {
      item.isSearch = e.target.checked;
    },

    /**
     *排序改变
     */
    isSortChange(item, e) {
      item.isSort = e.target.checked;
    },

    /**
     *默认改变
     */
    isSortDefalutChange(item, e) {
      item.isSortDefalut = e.target.checked;
    },

    /**
     *Asc改变
     */
    isSortAscChange(item, e) {
      item.isSortAsc = e.target.checked;
    },

    /**
     *合计改变
     */
    isTotalChange(item, e) {
      item.isTotal = e.target.checked;
    },

    /**
     *分页改变
     */
    isPagingChange(e) {
      this.list.isPaging = e.target.checked;
    },

    /**
     *多选改变
     */
    isMultipleChange(e) {
      this.list.isMultiple = e.target.checked;
    },
  },
};
</script>

<style lang="less" scoped>
.steps-content {
  margin-top: 16px;
  border: 1px dashed #e9e9e9;
  border-radius: 6px;
  background-color: #fafafa;
  min-height: 200px;
}

.steps-action {
  margin-top: 10px;
  text-align: right;
}

.close-box {
  bottom: 100px !important;
}

.drag-btn {
  cursor: move;
}
</style>
